﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Printing;
using System.Collections.Specialized;
using System.Net;

namespace Läxomatic
{
    public partial class laggtillcourse : Form
    {
        //Arrayer för att lagra tooltips
        private List<string> _arrItemToolTips = new List<string>();
        private List<string> _arrTaskFilesToolTips = new List<string>();
        private Tabell<string> _ListBoxPosts = new Tabell<string>();
        private string _lastTip = "";
       //Sätter alla värden, och tooltips
        public laggtillcourse()
        {
            InitializeComponent();
            string temp = Safety.getSalt();
            txt_code.Text = temp.Substring(temp.Length - 7);
            dtpick_deadline.Format = DateTimePickerFormat.Custom;
            dtpick_deadline.CustomFormat = "yyyy-MM-dd  HH:mm";  
            dtpick_deadline.Value = DateTime.Now;

            List<string> kursnamn = new Tabell<string>(Myskul.Command("SELECT name FROM course;")).getColumn(0);
            foreach (string name in kursnamn)
            {
                combo_selectTaskCourse.Items.Add(name);
                combo_courseName.Items.Add(name);
            }
            SavedData.tooltip.InitialDelay = 10;
            SavedData.tooltip.AutoPopDelay = 600000;
            SavedData.tooltip.SetToolTip(txt_fileType,"Lämna tom för valfri, ange annars filändelser i en kommaseparerad lista\nExempel:\"cpp;h\"");
        }
        //Lägger till/uppdaterar en kurs, efter att ha kollat så att alla värden är inmatade.
        private void btn_addCourse_Click(object sender, EventArgs e)
        {
            if (rbtn_new.Checked == true)
            {
                if (txt_Coursename.Text != "" && txt_code.Text != "" && txt_CourseDesc.Text != "")
                {
                    Myskul.Command("insert into course ( name, text, code) values ('" + txt_Coursename.Text + "','" + txt_CourseDesc.Text + "','" + txt_code.Text + "');");
                    MessageBox.Show("Ny kurs tillagd!");
                    SavedData.mainform.UpdateCourseList();
                    SavedData.mainform.DeleteCourse();
                    updateLboxTasks();
                }
                else
                {
                    MessageBox.Show("Du måste mata in alla fält!");
                }
            }
            if (rbtn_edit.Checked == true)
            {
                if (combo_courseName.Text != "" && txt_code.Text != "" && txt_CourseDesc.Text != "")
                {
                    Myskul.Command("UPDATE `course` SET `text`='" + txt_CourseDesc.Text + "',`code`='" + txt_code.Text + "' WHERE name ='"+ combo_courseName.Text+"';");
                    MessageBox.Show("Kursen " + combo_courseName.Text + " har blivit ändrad.");
                }
                else
                {
                    MessageBox.Show("Du måste välja kurs och mata in alla fält!");
                }
            }
        }
        //Det som händer så man väljer att editera en kurs, istället för att skapa en ny. Fyller i diverse fält/listor.
        private void rbtn_edit_CheckedChanged(object sender, EventArgs e)
        {
            if (rbtn_edit.Checked)
            {
                combo_courseName.Visible = true;
                txt_Coursename.Visible = false;
                btn_delete.Enabled = true;
                lbox_tasks.Enabled = true;
                combo_courseName.SelectedIndex = 0;
                groupBox1.Text = "Kurs " + combo_courseName.Text + " (Edit)";
            }
            else
            {
                string temp = Safety.getSalt();
                txt_code.Text = temp.Substring(temp.Length - 7);
                txt_CourseDesc.Text = "Beskrivning...";
                groupBox1.Text = "Kurs " + combo_courseName.Text;

                combo_courseName.Visible = false;
                txt_Coursename.Visible = true;
                btn_delete.Enabled = false;
                lbox_tasks.Enabled = false;
            }

        }
        //Fyller i relevanta värden då man byter markerad kurs i listboxen
        private void combo_courseName_SelectedIndexChanged(object sender, EventArgs e)
        {
            List<string> CourseInfo = new Tabell<string>(Myskul.Command("SELECT text, code FROM course WHERE name ='" + combo_courseName.Text + "';")).getRow(0);
            txt_code.Text = CourseInfo[1];
            txt_CourseDesc.Text = CourseInfo[0];
            updateLboxTasks();
            SavedData.tooltip.SetToolTip(combo_courseName, combo_courseName.Text);

            ComboBox temp= (ComboBox)sender;
            combo_selectTaskCourse.SelectedIndex = temp.SelectedIndex;
        }
        //Ändrar tooltip beroende på vilken kurs som väljs. Observera att den här ändras av ovanstående funktion.
        private void combo_selectTaskCourse_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox cbox = (ComboBox)sender;
            SavedData.tooltip.SetToolTip(combo_selectTaskCourse, cbox.Text);
        }
        //Tar bort texten "Beskrivning..." Då man merkerar rutan
        private void txt_CourseDesc_Click(object sender, EventArgs e)
        {
            if (txt_CourseDesc.Text == "Beskrivning...")
                txt_CourseDesc.Text = "";
        }
        //Fyller i listboxen med tasks, och sätter tooltips.
        private void updateLboxTasks()
        {
            lbox_tasks.Items.Clear();
            _arrItemToolTips.Clear();
            _ListBoxPosts = new Tabell<string>(Myskul.Command("SELECT t.name FROM task AS t JOIN course AS c ON (t.courseId=c.id) WHERE c.name ='" + combo_courseName.Text + "';"));
            foreach (string x in _ListBoxPosts.getColumn(0))
            {
                if (x.Length > 17)
                    lbox_tasks.Items.Add(x.Remove(15) + "..");
                else
                    lbox_tasks.Items.Add(x);
                this._arrItemToolTips.Add(x);
            }
            if (lbox_tasks.Items.Count > 0)
                lbox_tasks.SelectedIndex = 0;


        }
        //Visar tooltips på hover
        private void lbox_tasks_MouseMove(object sender, MouseEventArgs e)
        {
            ListBox listBox = (ListBox)sender;
            int index = listBox.IndexFromPoint(e.Location);
            if (index > -1 && index < listBox.Items.Count)
            {

                string tip = this._arrItemToolTips[index];
                if (tip != _lastTip)
                {
                    SavedData.tooltip.SetToolTip(listBox, tip);
                    _lastTip = tip;
                }
            }
        }
        //Tar bort uppgifter
        private void btn_delete_Click(object sender, EventArgs e)
        {
            DialogResult dialogres = MessageBox.Show("Vill du verkligen ta bort uppgiften '" + _arrItemToolTips[lbox_tasks.SelectedIndex] + "'", " ", MessageBoxButtons.YesNo);
            if (dialogres == DialogResult.Yes)
            {
                Myskul.Command("DELETE FROM task WHERE name = '" + _arrItemToolTips[lbox_tasks.SelectedIndex] + "';");
            }
            SavedData.mainform.UpdateCourseList();
            updateLboxTasks();
        }
        //Då man väljer en annan uppgift matas alla fält in, namn, textm poäng, deadline, filtyper
        private void lbox_tasks_SelectedIndexChanged(object sender, EventArgs e)
        {

            List<string> taskInfo = new Tabell<string>(Myskul.Command("SELECT deadline,text,maxpoints,id FROM task WHERE name='" + _arrItemToolTips[lbox_tasks.SelectedIndex] + "';")).getRow(0);
            txt_TaskName.Text = _arrItemToolTips[lbox_tasks.SelectedIndex];
            lbl_selectedTask.Text = _arrItemToolTips[lbox_tasks.SelectedIndex]; 
            txt_TaskPoints.Text = taskInfo[2];
            txt_TaskText.Text = taskInfo[1];
            System.DateTime dateTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0);
            dtpick_deadline.Value = dateTime.AddSeconds(Convert.ToInt32(taskInfo[0]));

            List<string> currentlyAllowedFileTypes = new Tabell<string>(Myskul.Command("SELECT f.filetype FROM filetype f JOIN task_filetype tf ON (f.id = tf.filetypeid) WHERE tf.taskId ='" + taskInfo[3] + "';")).getColumn(0);
            txt_fileType.Text = "";
            foreach (string str in currentlyAllowedFileTypes)
            {
                txt_fileType.Text += ";" + str.Substring(1);
            }
            if(txt_fileType.Text!="")
                txt_fileType.Text = txt_fileType.Text.Substring(1);
            UpdateTaskFiles();
        }
        //Lägger till/ändrar en uppgift i databasen, kollar först så att alla värden är ifyllda, sen huruvida uppgiften bara ska ändras (den finns markerad i lsitan över uppgifter) för att sedan ändra/lägga till den. 
        private void btn_addTask_Click(object sender, EventArgs e)
        {
            if (txt_TaskName.Text == "" || txt_TaskText.Text == "" || txt_TaskPoints.Text == "" || combo_selectTaskCourse.Text == "")
            {
                MessageBox.Show("Du måste ha en kurs vald, och alla värden ifyllda!");
                return;
            }
            Tabell<string> AllFileTypes = new Tabell<string>(Myskul.Command("SELECT filetype, id FROM filetype;"));
            List<string> AllFileTypeNames = AllFileTypes.getColumn(0);
            List<string> selectedFileTypes= new List<string>();
            selectedFileTypes.AddRange(txt_fileType.Text.Split(';'));

            string wrongFileType = "";
            foreach (string str in selectedFileTypes)
            {
                string temp = str.ToLower();
                if (AllFileTypeNames.IndexOf(temp) == -1 && AllFileTypeNames.IndexOf("." + temp) == -1&&temp!="")
                {
                    wrongFileType +=  temp + ", ";
                }
            }
            if (wrongFileType != "")
            {
                MessageBox.Show("Databasen har inget stöd för filer av typ " + wrongFileType + " tyvärr.");
                return;
            }
            

            TimeSpan ts = (dtpick_deadline.Value - new DateTime(1970, 1, 1, 0, 0, 0));
            double unixTime = ts.TotalSeconds;

            if (lbox_tasks.SelectedIndex !=-1&&txt_TaskName.Text == _arrItemToolTips[lbox_tasks.SelectedIndex])
            {
                Myskul.Command("UPDATE task SET `deadline`='" + Convert.ToInt32(unixTime) + "',`text`='" + txt_TaskText.Text + "',`maxpoints`='" + txt_TaskPoints.Text + "' WHERE name='" + txt_TaskName.Text + "';");
                MessageBox.Show("Uppgift " + txt_TaskName.Text + " ändrad!");
                string taskId = new Tabell<string>(Myskul.Command("SELECT id FROM task WHERE name = '" + txt_TaskName.Text + "';"))[0, 0];
                Tabell<string> temp = new Tabell<string>(Myskul.Command("SELECT f.filetype FROM filetype f JOIN task_filetype tf ON (f.id = tf.filetypeid) WHERE tf.taskId ='" + taskId + "';"));
                List<string> currentlyAllowedFileTypes = new List<string>();
                if (!temp.isEmpty())
                    currentlyAllowedFileTypes = temp.getRow(0);
            }
            else
            {
                string courseId = new Tabell<string>(Myskul.Command("SELECT id FROM course WHERE name = '" + combo_courseName.Text + "';"))[0, 0];
                Myskul.Command("INSERT INTO `task`(`name`, `deadline`, `text`, `courseId`, `maxpoints`) VALUES ('" + txt_TaskName.Text + "','" + Convert.ToInt32(unixTime) + "','" + txt_TaskText.Text + "','" + courseId + "','" + txt_TaskPoints.Text + "');");
            }


            this.updateLboxTasks();
        }
        //Ger en visuell indikator ifall man ändrar elelr lägger till.
        private void txt_TaskName_TextChanged(object sender, EventArgs e)
        {
            if (lbox_tasks.SelectedIndex!=-1 && txt_TaskName.Text == _arrItemToolTips[lbox_tasks.SelectedIndex])
                groupBox2.Text = "Uppgift " + txt_TaskName.Text + " (Ändra)";
            else
                groupBox2.Text = "Uppgift " + txt_TaskName.Text + " (Skapa)";
        }
        //Visar ett emddelande för formateringshjälp.
        private void btn_help_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Kursen laddas in mha en kommaseparerad textfil, med formateringen:\nKursnamn;Ping pong-inloggning;\nStatus för uppgift ett(0=Har ej uppgiften,1=Ej obligatorisk,2=Obligatorisk);\nStatus för uppgift två...\nExempel: dalgo;mojo1024;0;1;2;1;krjo1023;1;0;2;1");
        }
        // Öppnar dialogrutan för att öppna en kursfil, hämtar först relevanta data, kollar så att kursen som angetts har samma antal uppgifter som filen, för att sedan mata in poster.
        private void btn_browse_Click(object sender, EventArgs e)
        {
             string[] temp = browseFile();
             DialogResult dialogres = MessageBox.Show("Vill du verkligen in från filen '" + temp[1] + "'", " ", MessageBoxButtons.YesNo);
             if (dialogres == DialogResult.No)
                 return;
             if (temp[1] == "")
                 return;

            string input = temp[0];

            List<string> inputList = new List<string>();
            inputList.AddRange(input.Split(';'));

            string course = inputList[0];
            inputList.RemoveAt(0);

            List<List<string>> tempLogInData = new List<List<string>>();

            List<string> user = new List<string>();
            int taskCount = new Tabell<string>(Myskul.Command("SELECT * FROM task t JOIN course c ON (c.id=t.courseId) WHERE c.name='"+ course +"';")).Length();
            
            foreach (string str in inputList)
            {
                try
                {
                    int.Parse(str);
                }
                catch
                {
                    if (taskCount + 1 != user.Count&&user.Count!=0)
                    {
                        MessageBox.Show("Den inmatade kursen har fel antal uppgifter!");
                        return;
                    }
                    if (taskCount ==0)
                    {
                        MessageBox.Show("Den inmatade kursen felformaterad, eller saknar uppgifter!");
                        return;
                    }
                    List<string> tempUser = addUser(user, course);
                    if (tempUser != null)
                        tempLogInData.Add(tempUser);
                    user.Clear();
                    user.Add(str);
                    continue;
                }
                user.Add(str);
            }
            List<string> tempUser2 = addUser(user, course);
            if (tempUser2 != null)
                tempLogInData.Add(tempUser2);

            string passtemp="";
            for (int i = 0; i < tempLogInData.Count; i++)
            {
                for (int j = 0; j < tempLogInData[i].Count; j++)
                {
                    passtemp += tempLogInData[i][j]+"  ";
                }
                passtemp += "\n";
            }
            txt_logInInfo.Text ="Nya användaruppgifter:\r\nAnv.namn   Lösenord\r\n" + passtemp;

        }
        //Lägger till en användare baserat på data från textfilen.
        private List<string> addUser(List<string> user, string course)
        {
            if (user.Count == 0)
                return null;

            string username = user[0];
            user.RemoveAt(0);

             Tabell<string> tempId = new Tabell<string>(Myskul.Command("SELECT id from user WHERE loginname='"+ username +"';"));
             bool userDontExist = tempId.isEmpty();
             string userId = "";

            List<string> temp = new List<string>();
            string courseId = new Tabell<string>(Myskul.Command("SELECT id FROM course WHERE name ='"+course+"';"))[0,0];

            if (userDontExist)
            {
                string tempPass = Safety.getSalt();
                string password = tempPass.Substring(tempPass.Length - 7);
                string salt = Safety.getSalt();
                string checksum = Safety.getHashSha256(salt + username + password, 17);
                Myskul.Command("INSERT INTO `user`(`loginname`, `salt`, `checksum`) VALUES ('" + username + "','" + salt + "','" + checksum + "')");
                userId = new Tabell<string>(Myskul.Command("SELECT id FROM user WHERE loginname='"+username+"';"))[0, 0];
                Myskul.Command("INSERT INTO `student`(`userId`) VALUES ('" + userId + "')");
                temp.Add(username);
                temp.Add(password);
            }
            else
            {
                temp = null;
                userId = tempId[0, 0];
            }
            Myskul.Command("INSERT INTO `user_course`(`userId`, `courseId`) VALUES ("+userId+","+courseId+")");
            string studentId = new Tabell<string>(Myskul.Command("SELECT `id` FROM `student` WHERE userId= '"+userId+"';"))[0, 0];

            List<string> taskIds = new Tabell<string>(Myskul.Command("SELECT id FROM task WHERE courseId='"+courseId+"';")).getColumn(0);
            for(int i =0;i<taskIds.Count;i++)
            {
                if (user[i] == "1")
                    Myskul.Command("INSERT INTO `submit`(`studentId`, `taskId`, `points`, `submitStatus`, `gradeStatus`, `mandatory`) VALUES ('" + studentId + "','" + taskIds[i] + "',0,0,0,0)");
                if (user[i] == "2")
                    Myskul.Command("INSERT INTO `submit`(`studentId`, `taskId`, `points`, `submitStatus`, `gradeStatus`, `mandatory`) VALUES ('" + studentId + "','" + taskIds[i] + "',0,0,0,1)");
            }
            return temp;
 
        }
        // Öppnar dialogrutan för att öppna en kursfil
        private string[] browseFile()
        {
            string[] temp = new string[2];
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "Open the text file you wish";
            ofd.InitialDirectory = @"c:\";
            ofd.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                temp[1] = ofd.FileName;
                StreamReader sr = File.OpenText(ofd.FileName);
                string s = sr.ReadLine();
                StringBuilder sb = new StringBuilder();
                while (s != null)
                {
                    sb.Append(s);
                    s = sr.ReadLine();
                }
                sr.Close();
                temp[0]= sb.ToString();
                return temp;
            }
            temp[0] = "";
            temp[1] = "";
            return temp;
        }
        //Skapar ett dokument med info om inloggningsuppgifter.
        private void btn_print_Click(object sender, EventArgs e)
        {
            if(txt_logInInfo.Text=="Login-info kommer här..")
                MessageBox.Show("Finns inga elever tillgängliga");

            PrintDocument p = new PrintDocument();
            p.PrintPage += delegate(object sender1, PrintPageEventArgs e1)
            {
                e1.Graphics.DrawString(txt_logInInfo.Text, new Font("Times New Roman", 12), new SolidBrush(Color.Black), new RectangleF(0, 0, p.DefaultPageSettings.PrintableArea.Width, p.DefaultPageSettings.PrintableArea.Height));

            };
            try
            {
                p.Print();
            }
            catch (Exception ex)
            {
                throw new Exception("Exception Occured While Printing", ex);
            }
        }
        //Lägger till en fil till en uppgift
        private void bt_addfile_Click(object sender, EventArgs e)
        {
            string[] temp = new string[2];
            if (lbox_tasks.Items.Count > 0 &&_arrItemToolTips[lbox_tasks.SelectedIndex] != null)
            {
                temp = SelectFile();
            }
            string name = temp[0].Substring(temp[0].LastIndexOf(@"\") + 1);
            string hash = temp[1];
            string taskID = new Tabell<string>(Myskul.Command("SELECT id FROM task WHERE name='" + _arrItemToolTips[lbox_tasks.SelectedIndex] + "';"))[0, 0];
            Myskul.Command("INSERT INTO `task_file`(`taskId`, `filename`, `filenameHash`) VALUES ('" + taskID + "','" + name + "','" + hash + "')");
            UpdateTaskFiles();
        }
        //Väljer fil som skall läggas till
        private string[] SelectFile()
        {
            string path = browseFile()[1];
            NameValueCollection nvc = new NameValueCollection();
            nvc.Add("johan_johan", "Johan123");
            string url = "http://webbins.se/~johan.tmp/task_files/";
            string hash = "abc";
            //UploadFile(path,url,hash);
            string[] temp = new string[2];
            temp[0] = path;
            temp[1] = hash;
            return temp;


        }
        //Laddar upp själva filen.
        private void UploadFile(string path,string url,string hash)
        {
        try
	        {
            //create WebClient object
	        WebClient client = new WebClient();

            string myFile = path;

            NetworkCredential nc = new NetworkCredential("johan_johan", "Johan123");
            client.Credentials = nc;
	        client.UploadFile(url+hash, "PUT", myFile);
	         
	        client.Dispose();
	        }
	    catch (Exception err)
	        {
            MessageBox.Show(err.Message);
            }
        }
        //Uppdaterar listan ööver uppgiftens filer.
        private void UpdateTaskFiles()
        {
            _arrTaskFilesToolTips.Clear();
            lbox_TaskFiles.Items.Clear();
            if (_arrItemToolTips[lbox_tasks.SelectedIndex] != null)
            {
                string taskID = new Tabell<string>(Myskul.Command("SELECT id FROM task WHERE name='" + _arrItemToolTips[lbox_tasks.SelectedIndex] + "';"))[0, 0];
                Tabell<string> temp = new Tabell<string>(Myskul.Command("SELECT filename FROM task_file WHERE taskId='"+taskID+"';"));
                List<string> TaskFileNames = new List<string>();
                if(!temp.isEmpty())
                    TaskFileNames = temp.getColumn(0);
                foreach (string str in TaskFileNames)
                {
                    if (str.Length > 17)
                        lbox_TaskFiles.Items.Add(str.Remove(15) + "..");
                    else
                        lbox_TaskFiles.Items.Add(str);
                    this._arrTaskFilesToolTips.Add(str);
                }
            }
        }
        //tar bort en uppgifts fil
        private void brn_deleteTaskFile_Click(object sender, EventArgs e)
        {
            if (_arrItemToolTips[lbox_tasks.SelectedIndex] != null)
            {
                Myskul.Command("DELETE FROM task_file WHERE filename='" + _arrTaskFilesToolTips[lbox_TaskFiles.SelectedIndex] + "';");
            }
        }
        //Lägger till granskare (fyra funktioner)
        private void btn_addReviewers_Click(object sender, EventArgs e)
        {
            string kursId ="";
            List<string> studentId = new Tabell<string>(Myskul.Command("SELECT s.id FROM student AS s JOIN user_course AS uc ON (uc.userId = s.userId)	WHERE uc.courseId = '"+kursId+"';")).getColumn(0);
            foreach (string id in studentId)
            {
                randInspectorsOut(id, kursId);
				randInspectorsIn(id, kursId);
            }
        }
        private void randInspectorsIn(string id, string kursId)
        {
            Tabell<string> result = new Tabell<string>(Myskul.Command("SELECT s.taskId, s.id FROM submit AS s JOIN task AS t ON(t.id = s.taskId) WHERE s.studentId = '" + id + "' AND t.courseId = '" + kursId + "';"));
            for(int i = 0; i < result.Length();i++)
            {
                List<string> studentId = new Tabell<string>(Myskul.Command("SELECT s.studentId FROM submit AS s WHERE s.taskId = '" + kursId + "' AND s.studentId != '"+ id +"'	ORDER BY RAND()	LIMIT 2;")).getColumn(0);
                for(int j = 0; j < studentId.Count;j++)
                {
                    insertInspector(studentId[j], result.getColumn(1)[j]);
                }
            }
        }
        private void randInspectorsOut(string id, string kursId)
        {
            List<string> taskId = new Tabell<string>(Myskul.Command("SELECT s.taskId FROM submit AS s JOIN task AS t ON (t.id = s.taskId) WHERE s.studentId = '" + id + "' AND t.courseId = '" + kursId + "';")).getColumn(0);
            foreach (string tId in taskId)
            {
                List<string> submitId = new Tabell<string>(Myskul.Command("SELECT s.id AS id FROM submit AS s JOIN task AS t ON(t.id = s.taskId) AND t.courseId = '"+kursId+"' AND t.id = '"+taskId+"' AND s.studentId != '"+id+"' ORDER BY RAND() LIMIT 2;")).getColumn(0);
                foreach (string suId in submitId)
                {
                    insertInspector(id, suId);  
                }  
            }
        }
        private void insertInspector(string studentId, string submitId)
        {
            Myskul.Command("INSERT INTO student_comment (studentId, submitId) VALUES ('" + studentId + "', '" + submitId + "');");
        }
    }
}
